/// @tags: TreeChainPartition by Length
#include <cctype>
#include <cstdio>
#include <vector>

typedef unsigned int uint;

template <typename T>
inline T &read(T &x) {
  x = 0;
  bool f = false;
  short ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = true;
    ch = getchar();
  }
  while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ '0'), ch = getchar();
  if (f) x = -x;
  return x;
}

uint sid;
inline uint get(uint x) {
  x ^= x << 13, x ^= x >> 17, x ^= x << 5;
  return sid = x;
}

const int N = 5e5 + 5, bit = 19;
int n, q, f[bit][N], dep[N], hbit[N], top[N], son[N], dis[N];
int e_cnt, heads[N];
std::vector<int> ffa[N], sons[N];

struct Edge {
  int v, nxt;
} e[N];

inline void add(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
}

void dfs1(int u) {
  for (int i = 1; i < bit; ++i) { f[i][u] = f[i - 1][f[i - 1][u]]; }
  for (int i = heads[u], v; i; i = e[i].nxt) {
    f[0][v = e[i].v] = u, dep[v] = dis[v] = dep[u] + 1;
    dfs1(v);
    if (dis[v] > dis[son[u]]) dis[u] = dis[v], son[u] = v;
  }
}

void dfs2(int u) {
  if (u == top[u]) {
    for (int i = 0, tf = u, ts = u, lim = dis[u] - dep[u]; i <= lim; ++i)
      ffa[u].push_back(tf), tf = f[0][tf], sons[u].push_back(ts), ts = son[ts];
  }
  if (son[u]) top[son[u]] = top[u], dfs2(son[u]);
  for (int i = heads[u], v; i; i = e[i].nxt) {
    if ((v = e[i].v) != son[u]) { top[v] = v, dfs2(v); }
  }
}

inline int query(int x, int k) {
  if (!k) return x;
  x = f[hbit[k]][x], k -= 1 << hbit[k], k -= dep[x] - dep[top[x]], x = top[x];
  return k >= 0 ? ffa[x][k] : sons[x][-k];
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen64("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen64("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("TCPbyLength.in", "r", stdin);
  freopen("TCPbyLength.out", "w", stdout);
#endif
#endif

  read(n), read(q), read(sid);
  hbit[0] = -1;
  for (int i = 1; i <= n; ++i) {
    hbit[i] = hbit[i >> 1] + 1;
    add(read(f[0][i]), i);
  }
  long long ans = 0, lans = 0;
  int rt = e[heads[0]].v;
  f[0][rt] = top[rt] = rt, dep[rt] = 1;
  dfs1(rt), dfs2(rt);
  for (int x, k, i = 1; i <= q; ++i) {
    x = (get(sid) ^ lans) % n + 1, k = (get(sid) ^ lans) % dep[x];
    ans ^= static_cast<long long>(i) * (lans = query(x, k));
  }
  printf("%lld", ans);
  return 0;
}